package io.xxx.xbutler.sdk;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import io.xxx.xbutler.sdk.domain.Token;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.map.HashedMap;
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.net.URI;
import java.util.Map;
import java.util.Objects;

@Slf4j
public class TanJingClient {

    private final RestTemplate restTemplate;

    private final TokenProvider tokenProvider;

    private final String merchant;

    private final String secret;

    private final static String DOMAIN = "https://gateway.tanjingpaas.com:8091";

    public TanJingClient(String merchant, String secret, TokenProvider tokenProvider, RestTemplate restTemplate) {
        this.tokenProvider = tokenProvider;
        this.merchant = merchant;
        this.secret = secret;
        this.restTemplate = restTemplate;
    }

    @SneakyThrows
    public <T extends TanJingRequest<R>, R extends TanJingResponse> R execute(T request) {
        URI url = UriComponentsBuilder.fromUriString(DOMAIN)
                .path(request.path())
                .build()
                .toUri();
        Map<String, Object> params = new HashedMap<>(request.params());
        params.put(request.merchantName(), merchant);
        HttpHeaders headers = new HttpHeaders();
        Token token = tokenProvider.getToken(DOMAIN, merchant, secret);
        headers.add("token", token.getValue());
        RequestEntity<?> requestEntity = new RequestEntity<>(params, headers, HttpMethod.POST, url);
        ResponseEntity<JSONObject> responseEntity = restTemplate.exchange(requestEntity, JSONObject.class);
        HttpStatusCode statusCode = responseEntity.getStatusCode();

        if (!statusCode.is2xxSuccessful()) {
            log.error(buildLog(url, params, responseEntity.getStatusCode(), "失败"));
            return null;
        }
        JSONObject body = responseEntity.getBody();
        log.debug(buildLog(url, params, body, "成功"));

        if (Objects.isNull(body)) { // 不应该发生
            log.error(buildLog(url, params, "", "失败"));
            return null;
        }
        return body.toJavaObject(request.responseType());
    }

    private String buildLog(URI url, Object params, Object response, String s) {
        return String.format("调用探鲸平台%s[url:%s, request:%s, response:%s]", s, url, JSON.toJSONString(params), JSON.toJSONString(response));
    }
}
